﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using WatchSMSXML.Settings;
using System.Xml.Serialization;

public class ControlCentre
{
    public static void Main()
    {
        //Create an instance of the FileSystemWatcher
        FileSystemWatcher watcher = new FileSystemWatcher();

        Console.WriteLine("Started....");

        watcher.Path = Path.GetDirectoryName(AppSettings.WatchFolder);
        watcher.Filter = AppSettings.WatchFilter;

        Console.WriteLine("Watching folder: {0}", watcher.Path);
        Console.WriteLine("Filtering on: {0}", watcher.Filter);

        watcher.Created += new System.IO.FileSystemEventHandler(OnCreate);
        watcher.EnableRaisingEvents = true;

        Console.ReadLine();
    }
    public static void OnCreate(object source, FileSystemEventArgs e)
    {
        Console.WriteLine("File: {0} Created", e.FullPath);
        Console.WriteLine("Fire event for xml creation :-)");
        WaitForWriteToFinish(e.FullPath);

        int arseshitwank = GetImportID(e.Name);
        Console.WriteLine(arseshitwank);
        XmlSerializer ser = new XmlSerializer(typeof(smses));
        smses smss;
        using (Stream fileStream = File.Open(e.FullPath, FileMode.Open))
        {
            smss = (smses)ser.Deserialize(fileStream);
        }
        IDbConnection mySqlConnection = OpenConnection(AppSettings.MySQLDB, AppSettings.MySQLDatabase, AppSettings.MySQLUser, AppSettings.MySQLPassword);
        
        List<IDbCommand> commandsToExec = new List<IDbCommand>();

        foreach (var sms in smss.sms)
        {
            commandsToExec.Add(GetCommandToPushIntoDB(mySqlConnection, sms, arseshitwank));
        }
        RunAllCommands(mySqlConnection, commandsToExec);
    }
    private static int GetImportID(string name)
    {
        int retcode = 0;
        using (IDbConnection mySqlConnection = OpenConnection(AppSettings.MySQLDB, AppSettings.MySQLDatabase, AppSettings.MySQLUser, AppSettings.MySQLPassword))
        {
            var cmd = mySqlConnection.CreateCommand();
            cmd.CommandText = "add_import";
            cmd.CommandType = CommandType.StoredProcedure;
            var IncFileNameParam = cmd.CreateParameter();
            IncFileNameParam.ParameterName = "IncFileName";
            IncFileNameParam.Value = name;
            var ImportIdParam = cmd.CreateParameter();
            ImportIdParam.ParameterName = "ImportId";
            ImportIdParam.Direction = ParameterDirection.ReturnValue;
            cmd.Parameters.Add(IncFileNameParam);
            cmd.Parameters.Add(ImportIdParam);
            cmd.ExecuteNonQuery();
            retcode = (int)ImportIdParam.Value;
        }
        return retcode;
    }
    private static void WaitForWriteToFinish(string filePath)
    {
        Console.WriteLine("Waiting for write to finish {0}", filePath);
        DateTime start = DateTime.Now;

        DateTime timeout = start.AddMinutes(AppSettings.TimeoutMins);

        while (timeout > DateTime.Now)
        {
            try
            {
                File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.None).Dispose();
                Console.WriteLine("File available");
                System.Diagnostics.Debug.WriteLine("HURRAH!");
                return;
            }
            catch (Exception ex)
            {
                Console.WriteLine("File locked");
                System.Diagnostics.Debug.WriteLine("Locked");
                // swallow
            }
        }
    }
    private static IDbConnection OpenConnection(string server, string database, string userName, string password)
    {
        string connectionStringBase ="Server={0};user id={2};Password={2};database={1};;persist security info=False";
        Console.WriteLine(string.Format(connectionStringBase, server, database, userName, password));
        var connection = new MySql.Data.MySqlClient.MySqlConnection(string.Format(connectionStringBase, server, database, userName, password));
        connection.Open();
        return connection;
    }
    private static void RunAllCommands(IDbConnection connection, List<IDbCommand> commandsToExec)
    {
        var transaction = connection.BeginTransaction();
        try
        {
            foreach (var cmd in commandsToExec)
            {
                cmd.Transaction = transaction;
                cmd.ExecuteNonQuery();
            }
            transaction.Commit();
        }
        catch (Exception ex)
        {
            transaction.Rollback();
            throw;
        }
    }
    private static IDbConnection OpenConnection()
    {
        // return new MySqlCOnnection via connector
        throw new NotImplementedException();
    }
    private static IDbCommand GetCommandToPushIntoDB(IDbConnection mySqlConnection, smsesSms sms, int thisImportID)
    {
        var storedProc = mySqlConnection.CreateCommand();

        storedProc.CommandText = "add_message";
        storedProc.CommandType = CommandType.StoredProcedure;


        storedProc.Parameters.Add(CreateParameter(storedProc, "incImportID", thisImportID));
        storedProc.Parameters.Add(CreateParameter(storedProc, "incProtocol", sms.protocol));
        storedProc.Parameters.Add(CreateParameter(storedProc, "incSourcePhone", sms.address));
        storedProc.Parameters.Add(CreateParameter(storedProc, "incRawDate", sms.date));
        storedProc.Parameters.Add(CreateParameter(storedProc, "incType", sms.type));
        storedProc.Parameters.Add(CreateParameter(storedProc, "incSubject", sms.subject));
        storedProc.Parameters.Add(CreateParameter(storedProc, "incBody", sms.body));
        storedProc.Parameters.Add(CreateParameter(storedProc, "incToa", sms.toa));
        storedProc.Parameters.Add(CreateParameter(storedProc, "incScToa", sms.sc_toa));
        storedProc.Parameters.Add(CreateParameter(storedProc, "incServiceCentrePhone", sms.service_center));
        storedProc.Parameters.Add(CreateParameter(storedProc, "incRead", sms.read));
        storedProc.Parameters.Add(CreateParameter(storedProc, "incStatus", sms.status));
        storedProc.Parameters.Add(CreateParameter(storedProc, "incLocked", sms.locked));
        //storedProc.Parameters.Add(CreateParameter(storedProc, "incReadableDate", sms.readable_date));
        storedProc.Parameters.Add(CreateParameter(storedProc, "incContactName", sms.contact_name));
        return storedProc;
    }
    private static IDataParameter CreateParameter<T>(IDbCommand storedProc, string name, T value)
    {
        var parameter = storedProc.CreateParameter();
        parameter.ParameterName = name;
        parameter.Value = value;
        return parameter;
    }
}
